package com.miplus.ccrm.core.service.iou;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.miplus.ccrm.common.*;
import com.miplus.ccrm.core.controller.vo.credit.ValRadioVo;
import com.miplus.ccrm.core.controller.vo.ficase.*;
import com.miplus.ccrm.core.controller.vo.iou.*;
import com.miplus.ccrm.core.mapper.*;
import com.miplus.ccrm.core.pojo.*;
import com.miplus.ccrm.core.security.JCommonData;
import com.miplus.ccrm.core.service.ExportService;
import com.miplus.ccrm.core.service.collect.FiCreditcasesService;
import com.miplus.ccrm.core.service.collect.FiImportHistService;
import com.miplus.ccrm.core.service.strategy.CpCalllistTriggerQuerylinkService;
import com.miplus.ccrm.core.utils.EnumFiCaseQueue;
import com.miplus.ccrm.core.utils.EnumFiCaseStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class FiCasesServiceIouImpl implements FiCasesServiceIou{
    @Resource
    private ConCustomertagMapper conCustomertagMapper;
    @Resource
    private FiCreditcasesService caseService;
    @Resource
    private JCommonData jCommonData;
    @Resource
    private ExportService exportService;
    @Resource
    private FiImportHistService fiImportHistService;
    @Resource
    private CfgActivityMapper activityMapper;
    @Resource
    private CpCalllistTriggerMapper triggerMapper;
    @Resource
    private CfgActivityOthergrplinkMapper othergrplinkMapper;
    @Resource
    private CfgAssignratioMapper assignratioMapper;
    @Resource
    private CpCalllistTriggerQuerylinkService triggerQuerylinkService;

    private MPJLambdaWrapper getQueryWrapper(JSysUser user, ICaseReqVo paras)
    {
        String noinctags="";
        String $usrid=user.getUsrid();
        String tags= JPubUtils.getInString(paras.getCusttaglist());
        if(JPubUtils.IsNotEmpty(tags)){
            noinctags = JPubUtils.BoolToString(paras.getNoincludetags());
        }
        boolean viewAllCase= JUsrPerm.viewAllFiCase(user);
        return new MPJLambdaWrapper<FiCreditcases>()
                .innerJoin(ConCustomer.class, "cu", ConCustomer::getCustomernumber, FiCreditcases::getCustomernumber)
                .leftJoin(FiTask.class, "tk", FiTask::getTasknumber, FiCreditcases::getLastcctaskid)
                .apply(!viewAllCase,JPubUtils.getPuvViewSql($usrid))
                .eq(JPubUtils.IsNotEmpty(paras.getFicaseid()), FiCreditcases::getCreditcaseid, paras.getFicaseid())
                .in(JPubUtils.IsNotEmpty(paras.getStatus()), FiCreditcases::getStatus, paras.getStatus())
                .eq(JPubUtils.IsNotEmpty(paras.getCustnumber()), ConCustomer::getCustomernumber, paras.getCustnumber())
                .eq(JPubUtils.IsNotEmpty(paras.getCusttype()), ConCustomer::getType, paras.getCusttype())
                .likeRight(JPubUtils.IsNotEmpty(paras.getCustname()), ConCustomer::getCustname, paras.getCustname())
                .eq(JPubUtils.IsNotEmpty(paras.getRisklevel()), ConCustomer::getRisklevel, paras.getRisklevel())
                .eq(JPubUtils.IsNotEmpty(paras.getOpenacctcertno()), ConCustomer::getOpenacctcertno, paras.getOpenacctcertno())
                .eq(JPubUtils.IsNotEmpty(paras.getContractnumber()), FiCreditcases::getCreditAcct, paras.getContractnumber())
                .in(JPubUtils.IsNotEmpty(paras.getProdtype()), FiCreditcases::getProdtype, paras.getProdtype())
                .eq(JPubUtils.IsNotEmpty(paras.getSendtodept()), FiCreditcases::getSendtodept, paras.getSendtodept())
                .eq(JPubUtils.IsNotEmpty(paras.getSendtousr()), FiCreditcases::getSendtousr, paras.getSendtousr())
                .eq(JPubUtils.IsNotEmpty(paras.getCcc()),FiCreditcases::getCcc,paras.getCcc())
                .eq(JPubUtils.IsNotEmpty(paras.getDistbatchid()), FiCreditcases::getDistbatchid, paras.getDistbatchid())
                .eq(JPubUtils.IsNotEmpty(paras.getBatchid()), FiCreditcases::getBatchid, paras.getBatchid())
                .ge(JPubUtils.IsNotEmpty(paras.getOdudPrin1()), FiCreditcases::getOdudPrin, paras.getOdudPrin1())
                .le(JPubUtils.IsNotEmpty(paras.getOdudPrin2()), FiCreditcases::getOdudPrin, paras.getOdudPrin2())
                .between(JPubUtils.IsNotEmpty(paras.getStartdt()), FiCreditcases::getCrdt, JPubUtils.StringToDate(paras.getStartdt()), JPubUtils.StringToDate(paras.getEnddt()))
                .between(JPubUtils.IsNotEmpty(paras.getDiststartdt()), FiCreditcases::getDistdt, JPubUtils.StringToDate(paras.getDiststartdt()), JPubUtils.StringToDate(paras.getDistenddt()))
                .between(JPubUtils.IsNotEmpty(paras.getAppointstartdt()), FiCreditcases::getAppointdt, JPubUtils.StringToDate(paras.getAppointstartdt()), JPubUtils.StringToDate(paras.getAppointenddt()))
                .between(JPubUtils.IsNotEmpty(paras.getInstartdt()), FiCreditcases::getIndt, JPubUtils.StringToDate(paras.getInstartdt()), JPubUtils.StringToDate(paras.getInenddt()))
                .between(JPubUtils.IsNotEmpty(paras.getRecystartdt()), FiCreditcases::getRecycledt, JPubUtils.StringToDate(paras.getRecystartdt()), JPubUtils.StringToDate(paras.getRecyenddt()))
                .between(JPubUtils.IsNotEmpty(paras.getLastccstartdt()), FiCreditcases::getLastccdt, JPubUtils.StringToDate(paras.getLastccstartdt()), JPubUtils.StringToDate(paras.getLastccenddt()))
                .eq(JPubUtils.IsNotEmpty(paras.getLastccresult()),FiTask::getResult,paras.getLastccresult())
                .ge(JPubUtils.IsNotEmpty(paras.getMthsodue1()), FiCreditcases::getMthsOdue, paras.getMthsodue1())
                .le(JPubUtils.IsNotEmpty(paras.getMthsodue2()), FiCreditcases::getMthsOdue, paras.getMthsodue2())
                .ge(JPubUtils.IsNotEmpty(paras.getMthsday1()), FiCreditcases::getMthsDay, paras.getMthsday1())
                .le(JPubUtils.IsNotEmpty(paras.getMthsday2()), FiCreditcases::getMthsDay, paras.getMthsday2())
                .eq(JPubUtils.IsNotEmpty(paras.getRepayday()),FiCreditcases::getRepaydt,paras.getRepayday())
                .in(JPubUtils.IsNotEmpty(paras.getFlevel()),ConCustomer::getFlevel,paras.getFlevel())
                .apply(JPubUtils.IsEqual(paras.getIsfiamort(), "1"), "fc_hasFiAmort(t.creditcaseid)>0")
                .apply(JPubUtils.IsEqual(paras.getIsfiamort(), "0"), "fc_hasFiAmort(t.creditcaseid)=0")
                .in(JPubUtils.IsNotEmpty(paras.getOpenacctcertnolist()), ConCustomer::getOpenacctcertno, paras.getOpenacctcertnolist())
                .in(JPubUtils.IsNotEmpty(paras.getContractlist()),FiCreditcases::getCreditAcct,paras.getContractlist())
                .eq(JPubUtils.IsNotEmpty(paras.getBillno()), FiCreditcases::getCollectno, paras.getBillno())
                .in(JPubUtils.IsNotEmpty(paras.getBillno()), FiCreditcases::getCollectno, paras.getBillnolist())
                .apply(JPubUtils.IsEqual(noinctags, 0),String.format("cu.customernumber in (select tag.custid from con_customertag tag where tag.custid=t.customernumber and tag.id in ('%s'))", tags))
                .apply(JPubUtils.IsEqual(noinctags, 1), String.format("cu.customernumber not in (select tag.custid from con_customertag tag where tag.custid=t.customernumber and tag.id in ('%s'))", tags))
                .exists(JPubUtils.IsNotEmpty(paras.getCustphone()), String.format("select 1 from con_contact ct where ct.customernumber=t.customernumber and ct.phone='%s'",paras.getCustphone()))
                .apply(JPubUtils.IsEqual(paras.getIscodebt(),"1"),"(select count(1) from fi_creditcases fi where fi.customernumber=t.customernumber and fi.ccc in('O','Q','S'))>1");
    }

    @Override
    public IPage<ICaseResVo> caseList(JSysUser user, ICaseReqVo paras)
    {
        String $usrid=user.getUsrid();
        String phnstar= JUsrPerm.getPermission(user,JUsrPerm.DISSTAR_PHN);
        String idstar= JUsrPerm.getPermission(user,JUsrPerm.DISSTAR_IDNO);
        //String cardstar= JUsrPerm.getPermission(user,JUsrPerm.DISSTAR_CARD);
        String orderbyid=caseService.getOrderByFiled(paras.getOrderbyid());
        MPJLambdaWrapper<FiCreditcases> quyWrapper=getQueryWrapper(user,paras);
        return caseService.selectJoinListPage(new Page<>(paras.getPageNum(), paras.getPageSize()),
                ICaseResVo.class,
                quyWrapper.selectAs(FiCreditcases::getCreditcaseid,ICaseReqVo::getFicaseid)
                        .selectAs("t.credit_acct", ICaseResVo::getContractnumber)
                        .selectAs("fun_getnames('COLLECT.STATUS',t.status)", ICaseResVo::getStatusdsc)
                        .selectAs("fun_getnames('CUST.TYPE',cu.type)", ICaseResVo::getCusttypedsc)
                        .selectAs("(select g.grpname from sys_grp g where g.grpid=t.sendtodept)", ICaseResVo::getSendtodeptdsc)
                        .selectAs("fun_getnames('COLLECT.ODUE',t.mths_odue)", ICaseResVo::getMthsOdue)
                        .selectAs("fun_getnames('COLLECT.QUEUE',t.ccc)", ICaseResVo::getCccdsc)
                        .selectAs("fun_getnames('FI.COLLECT.CHANNEL',t.prodtype)", ICaseResVo::getProdtypedsc)
                        .selectAs("(case when t.ccc='S' then 1 else 0 end)", ICaseResVo::getIsstopcase)
                        .selectAs("fun_getnames('CREDIT.ACCT.FLEVEL',cu.Flevel)",ICaseInfoVo::getFlevel)
                        .selectAs("tk.result", ICaseResVo::getLastccresult)
                        .selectAs(String.format("fi_starSecu('%s','%s',cu.custphone,'%s')", $usrid, JUsrPerm.DISSTAR_PHN, phnstar), ICaseResVo::getCustphone)
                        .selectAs(String.format("fi_starSecu('%s','%s',cu.openacctcertno,'%s')", $usrid, JUsrPerm.DISSTAR_IDNO, idstar), ICaseResVo::getOpenacctcertno)
                        .select(FiCreditcases::getStatus, FiCreditcases::getCcc, FiCreditcases::getProdtype,FiCreditcases::getIndt,FiCreditcases::getMddt,
                                FiCreditcases::getDistdt,FiCreditcases::getDistbatchid,FiCreditcases::getSendtodept, FiCreditcases::getSendtousr, FiCreditcases::getRepay,
                                FiCreditcases::getAppointdt, FiCreditcases::getLastccdt, FiCreditcases::getBindenddt, FiCreditcases::getStopautodistenddt,
                                FiCreditcases::getDistusr,FiCreditcases::getAssigndt,FiCreditcases::getAssignusr,FiCreditcases::getRecycledt,
                                FiCreditcases::getRecycleusr,FiCreditcases::getClosedt,FiCreditcases::getRepaydt,FiCreditcases::getLoanamt,FiCreditcases::getMthsDay,
                                FiCreditcases::getRepayday,FiCreditcases::getOdudPrin,FiCreditcases::getCollectno)
                        .select(ConCustomer::getCustomernumber, ConCustomer::getCustname, ConCustomer::getRisklevel, ConCustomer::getCorpname)
                        .orderByAsc(JPubUtils.IsEqual(paras.getOrderbyasc(),"1")&&JPubUtils.IsNotEmpty(orderbyid),orderbyid)
                        .orderByDesc(JPubUtils.IsEqual(paras.getOrderbyasc(),"2")&&JPubUtils.IsNotEmpty(orderbyid),orderbyid)
        );
    }

    @Override
    public QuyAmtSumVo getQueryDebtSum(JSysUser user, ICaseReqVo paras)
    {
        MPJLambdaWrapper<FiCreditcases> quyWrapper=getQueryWrapper(user,paras);
        return caseService.selectJoinOne(QuyAmtSumVo.class,
                quyWrapper.selectSum(FiCreditcases::getOdudPrin, QuyAmtSumVo::getAmtSum)
        );
    }

    @Override
    public ICaseInfoVo getCaseDetailInfo(JSysUser user, Integer ficaseid)
    {//单个查询也需要控制权限，防止页面输入creditcaseid直接打开
        String $usrid=user.getUsrid();
        String idstar= JUsrPerm.getPermission(user,JUsrPerm.DISSTAR_IDNO);
        String cardstar= JUsrPerm.getPermission(user,JUsrPerm.DISSTAR_CARD);
        //2024-07-24
        boolean viewAllCase=JUsrPerm.viewAllFiCase(user);
        ICaseInfoVo resVo=caseService.selectJoinOne(
                ICaseInfoVo .class,
                new MPJLambdaWrapper<FiCreditcases>()
                        .selectAs(FiCreditcases::getCreditcaseid,ICaseInfoVo::getFicaseid)
                        .selectAs("t.credit_acct", ICaseResVo::getContractnumber)
                        .selectAs("fun_getnames('COLLECT.STATUS',t.status)",ICaseInfoVo::getStatusdsc)
                        .selectAs("fun_getnames('CUST.TYPE',cu.type)",ICaseInfoVo::getCusttypedsc)
                        .selectAs("(select g.grpname from sys_grp g where g.grpid=t.sendtodept)",ICaseInfoVo::getSendtodeptdsc)
                        .selectAs("fun_getnames('COLLECT.ODUE',t.mths_odue)",ICaseInfoVo::getMthsOdue)
                        .selectAs("fun_getnames('COLLECT.QUEUE',t.ccc)", ICaseInfoVo::getCccdsc)
                        .selectAs("fun_getnames('FI.COLLECT.CHANNEL',t.prodtype)",ICaseInfoVo::getProdtypedsc)
                        .selectAs("fun_getnames('MARRIAGE.STATUS',cu.marrgstatus)",ICaseInfoVo::getMarrgstatus)
                        .selectAs("fun_getnames('CON.SEX',cu.gender)",ICaseInfoVo::getGender)
                        .selectAs("fun_getnames('CON.EDU',cu.heightedudegr)",ICaseInfoVo::getHeightedudegr)
                        .selectAs("fun_getnames('CON.PSTN',cu.pstn)",ICaseInfoVo::getPstn)
                        .selectAs("fun_getnames('CON.CERTTYPE',cu.openacctcerttype)", ICaseInfoVo::getOpenacctcerttype)
                        .selectAs("fun_getnames('BUSINESS.TYPE',t.prodtype)",ICaseInfoVo::getProdtypedsc)
                        .selectAs("(case when t.ccc='S' then 1 else 0 end)", ICaseInfoVo::getIsstopcase)
                        .selectAs("fun_getnames('CREDIT.ACCT.FLEVEL',cu.Flevel)",ICaseInfoVo::getFlevel)
                        .selectAs(String.format("fi_starSecu('%s','%s',cu.openacctcertno,'%s')",$usrid,JUsrPerm.DISSTAR_IDNO,idstar),ICaseInfoVo::getOpenacctcertno)
                        .selectAs(String.format("fi_starSecu('%s','%s',cu.debitcardno,'%s')", $usrid, JUsrPerm.DISSTAR_CARD, cardstar), ICaseInfoVo::getDebitcardno)
                        .selectAs("fc_hasFiAmort(t.creditcaseid)", ICaseInfoVo::getFiamortcount)
                        .apply(!viewAllCase,JPubUtils.getPuvViewSql($usrid))
                        .leftJoin(ConCustomer.class,"cu",ConCustomer::getCustomernumber,FiCreditcases::getCustomernumber)
                        .select(FiCreditcases::getStatus,FiCreditcases::getCcc,FiCreditcases::getCreditAcct,FiCreditcases::getMddt,
                                FiCreditcases::getProdtype,FiCreditcases::getIndt,FiCreditcases::getDistdt,FiCreditcases::getSendtodept,FiCreditcases::getSendtousr,FiCreditcases::getRepay,
                                FiCreditcases::getRepaydt,FiCreditcases::getOdudPrin,FiCreditcases::getAppointdt,FiCreditcases::getLastccdt,
                                FiCreditcases::getBindenddt,FiCreditcases::getStopautodistenddt,FiCreditcases::getLoanamt,FiCreditcases::getOdudPrin,FiCreditcases::getMthsDay,FiCreditcases::getRepayday,
                                FiCreditcases::getOverPrin,FiCreditcases::getInterestFee,FiCreditcases::getPenchgAcc,FiCreditcases::getOthExpense,FiCreditcases::getCollectno)
                        .select(ConCustomer::getCustomernumber,ConCustomer::getCustname,ConCustomer::getRisklevel,ConCustomer::getDepartment,ConCustomer::getCorpname,
                                ConCustomer::getAnnualincome,ConCustomer::getCustacctorgno,ConCustomer::getCustenname,ConCustomer::getCustemail,ConCustomer::getIsbankemply, ConCustomer::getBirthday)
                        .eq(FiCreditcases::getCreditcaseid,ficaseid)
        );
        List<ConCustomertag> custtags=conCustomertagMapper.selectJoinList(
                ConCustomertag.class,
                new MPJLambdaWrapper<ConCustomertag>()
                        .leftJoin(FiCreditcases.class,"fc",FiCreditcases::getCustomernumber,ConCustomertag::getCustid)
                        .selectAll(ConCustomertag.class)
                        .eq("fc.creditcaseid",ficaseid)
        );
        if(custtags!=null&&custtags.size()>0){
            List<String> tags=custtags.stream().map(ConCustomertag::getId).collect(Collectors.toList());
            resVo.setCusttags(tags);
        }

        return resVo;
    }

    private int bindFiCastList(List<Integer> caseList,JSysUser user,ICaseReqVo paras)
    {//2024-07-28
        //List<Integer> arr=new LinkedList<>();
        log.info("bindFiCastList:distMaxCount={}",JPubUtils.distMaxCount);
        MPJLambdaWrapper<FiCreditcases> quyWrapper=getQueryWrapper(user,paras);
        IPage<ICaseResVo> pages=caseService.selectJoinListPage(new Page<>(1, JPubUtils.distMaxCount),
                ICaseResVo.class,
                quyWrapper.selectAs(FiCreditcases::getCreditcaseid,ICaseResVo::getFicaseid)
        );
        log.info("bindFiCastList:total={},page={},size={}",pages.getTotal(),pages.getPages(),pages.getSize());
        pages.convert(u->{
            caseList.add(u.getFicaseid());
            return u;
        });
        //Collections.copy(caseList,arr);
        return caseList.size();
    }

    @Override
    public CmdResVo getOneRecyCount(JSysUser user, ICaseReqVo dataParas)
    {//2024-09-27 为了客户端异常处理
        int cnt=0;
        if(dataParas!=null){
            List<Integer> recylistID = new LinkedList<>();
            cnt = bindFiCastList(recylistID, user, dataParas);
            log.info("getOneRecyCount={}", cnt);
        }
        return new CmdResVo(cnt);
    }

    @Override
    public List<DistResVo> caseDistribute(JSysUser user, DistReqVo paras, ICaseReqVo distParas)
    {
        List<Integer> dataCaseList = paras.getFicaseList();
        if (paras.getIspredist() == JPubUtils.PRE_OPERATE) {
            if (distParas != null) {//使用查询条件取分配数据(一键分案)
                bindFiCastList(dataCaseList, user, distParas);
                log.info("caseDistribute:Count={}", dataCaseList.size());
                if(dataCaseList.size()==0){
                    throw new ServiceException(EnumRCode.NoFindPreDist.value, EnumRCode.NoFindPreDist.name);
                }
            }
        }

        return caseService.fiCaseDistribute(user,paras,dataCaseList);
    }

    @Override
    public List<DistResVo> caseAssign(JSysUser user, AssReqVo paras, ICaseReqVo distParas)
    {
        List<Integer> dataCaseList=null;
        if (paras.getIspreass() == JPubUtils.PRE_OPERATE) {
            dataCaseList = paras.getFicaseList();
            if (distParas != null) {//使用查询条件取分配数据(一键分案)
                bindFiCastList(dataCaseList, user, distParas);

                log.info("caseAssign:Count={}", dataCaseList.size());
                if(dataCaseList.size()==0){
                    throw new ServiceException(EnumRCode.NoFindPreDist.value, EnumRCode.NoFindPreDist.name);
                }
            }
        }

        return caseService.fiCaseAssign(user,paras,dataCaseList);
    }

    @Override
    public CmdResVo caseRecycle(JSysUser user, RecyReqVo paras, ICaseReqVo dataParas)
    {
        boolean oneRecycle=false;
        List<Integer> recylistID=paras.getFicaseList();
        if((paras.getRecymode()==JPubUtils.RECY_MODE_TOP)&&(dataParas!=null)){
            if(jCommonData.IsRecycleProcess()){
                log.info("fiCaseRecycle.IsRecycleProcess...");
                return new CmdResVo(0);
            }
            oneRecycle=true;
            //放到这里为了解决下面查询数据可能时间比较长时，客户端请求返回0，否则返回-1就结束了，2024-09-27
            jCommonData.SetRecycleProcess(0);
            recylistID=new LinkedList<>();
            bindFiCastList(recylistID,user,dataParas);
            //recylist=caseService.getRecyCaseList(recylistID);
            log.info("fiCaseRecycle.recylist={},mode={} oneRecycle",recylistID.size(),paras.getRecymode());
        }
        else{
            //recylist=caseService.getRecyCaseList(recylistID);
            log.info("fiCaseRecycle.recylist={},mode={}",recylistID.size(),paras.getRecymode());
        }

        return caseService.fiCaseRecycle(user,paras,recylistID,oneRecycle);
    }

    @Override
    public CmdResVo caseTranDist(JSysUser user, TranDistReqVo paras, ICaseReqVo distParas)
    {
        if(!JPubUtils.IsEqual(paras.getIsquydist(),"1")&&JPubUtils.IsEmpty(paras.getFicaseList())){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }

        List<Integer> distCaseList = paras.getFicaseList();
        if (JPubUtils.IsEqual(paras.getIsquydist(),"1")) {//使用查询条件取分配数据
            bindFiCastList(distCaseList, user, distParas);
        }

        return caseService.fiCaseTranDist(user,paras,distCaseList);
    }

    @Override
    public CmdResVo caseSaveAs(JSysUser user, ICaseReqVo paras, HttpServletResponse response)
    {
        String $usrid = user.getUsrid();
        int pagesize = paras.getPageSize();
        if (pagesize > JPubUtils.exportMaxCount) {
            paras.setPageSize(JPubUtils.exportMaxCount);
        }
        log.info("caseSaveAs:pagesize={}",pagesize);

        IPage<ICaseResVo> pages=caseList(user, paras);
        ArrayList arr=new ArrayList();

        String exptempid=JPubUtils.getExpTempID(paras.getExpfilename(),"案件表");
        String filename=JPubUtils.getExpFileName(
                paras.getExpfilename(),exptempid
        );
        pages.convert(u->{
            HashMap map=JPubUtils.toExportMap(u);
            if(map!=null) arr.add(map);
            return u;
        });
        CmdResVo resVo=exportService.ToExcel(
                response,
                arr,
                paras.getExpidlist(),
                paras.getExpnamelist(),
                filename,
                $usrid
        );

        int okcount=resVo.getCount();
        if(okcount>0){
            fiImportHistService.AddExportHist(
                    resVo.getKeyId(),
                    $usrid,
                    exptempid,
                    filename,
                    okcount
            );
        }
        arr.clear();

        return resVo;
    }

    @Override
    public CmdResVo getNextFiCaseID(JSysUser user,Integer ficaseid)
    {
        String usrid=user.getUsrid();
        String key=jCommonData.getQuyNextCaseDataKey(usrid);
        Object o=jCommonData.getData(key);
        if(o==null){
            log.warn("getNextFiCaseID({}):nofinddata={}",ficaseid,key);
            return new CmdResVo(0);
        }
        boolean bnext=false;
        Integer nextcaseid=0;
        IPage<ICaseResVo> pages=(IPage<ICaseResVo>)o;
        List<ICaseResVo> ll=pages.getRecords();
        for(ICaseResVo p : ll){
            if(p.getFicaseid().equals(ficaseid)){
                bnext=true;
            }
            else if(bnext){
                nextcaseid=p.getFicaseid();
                log.info("getNextFiCaseID({})->{}",ficaseid,p.getFicaseid());
                break;
            }
        }
        if(nextcaseid==0){//下一页
            log.info("getNextFiCaseID({}):find next page",ficaseid);
            key=jCommonData.getQuyNextCaseKey(usrid);
            o=jCommonData.getData(key);
            if(o==null){
                log.warn("getNextFiCaseID:nofindquypara={}",key);
                return new CmdResVo(0);
            }
            ICaseReqVo reqVo=(ICaseReqVo)o;
            int currpagenum=reqVo.getPageNum();
            reqVo.setPageNum(currpagenum+1);

            boolean b=jCommonData.setData(key,reqVo,JPubUtils.distExpiration*2);
            log.info("getNextFiCaseID({}):pagenum={},nextpagetnum={},ret={}",
                    ficaseid,currpagenum,reqVo.getPageNum(),b
            );
            IPage<ICaseResVo> quyResult=caseList(user,reqVo);
            ll=quyResult.getRecords();
            if(ll.size()<=0){
                log.info("getNextFiCaseID({}):quydata has last",ficaseid);
                return new CmdResVo(0);
            }
            nextcaseid=ll.get(0).getFicaseid();
            key=jCommonData.getQuyNextCaseDataKey(usrid);
            jCommonData.setData(key,quyResult,JPubUtils.distExpiration*2);
        }

        return new CmdResVo(1,nextcaseid.toString());
    }

    private MPJLambdaWrapper getQueryWrapper(Integer triggerid)
    {
        String noinctags="";
        CpCalllistTrigger trigger=triggerMapper.selectById(triggerid);
        if(trigger==null) return null;
        String tags= JPubUtils.getInString(trigger.getCusttags());
        if(JPubUtils.IsNotEmpty(tags)){
            noinctags = JPubUtils.BoolToString(trigger.getNoinctag());
        }
        MPJLambdaWrapper quyWrapper=new MPJLambdaWrapper<FiCreditcases>()
                .innerJoin(ConCustomer.class, "cu", ConCustomer::getCustomernumber, FiCreditcases::getCustomernumber)
                .ge(JPubUtils.IsNotEmpty(trigger.getMthsodue()), FiCreditcases::getMthsOdue, trigger.getMthsodue())
                .le(JPubUtils.IsNotEmpty(trigger.getMthsodue2()), FiCreditcases::getMthsOdue, trigger.getMthsodue2())
                .ge(JPubUtils.IsNotEmpty(trigger.getOverday1()), FiCreditcases::getMthsDay, trigger.getOverday1())
                .le(JPubUtils.IsNotEmpty(trigger.getOverday2()), FiCreditcases::getMthsDay, trigger.getOverday2())
                .apply(JPubUtils.IsEqual(noinctags, 0),String.format("cu.customernumber in (select tag.custid from con_customertag tag where tag.custid=t.customernumber and tag.id in ('%s'))", tags))
                .apply(JPubUtils.IsEqual(noinctags, 1), String.format("cu.customernumber not in (select tag.custid from con_customertag tag where tag.custid=t.customernumber and tag.id in ('%s'))", tags));

        quyWrapper=triggerQuerylinkService.buildQueryWrapper(quyWrapper,triggerid);

        return quyWrapper;
    }

    @Override
    public CmdResVo caseDistribute(JSysUser user,Integer tempid,String domode,Double amirate) {
        //domode=1手动，=2自动
        CfgActivity activity = activityMapper.selectById(tempid);
        if (activity == null){
            log.warn("caseDistribute({}).nofind activity",tempid);
            return new CmdResVo(0);
        }
        Integer triggerid=activity.getTriggerid();
        if(JPubUtils.IsEmpty(triggerid)){
            log.warn("caseDistribute({}).nofind triggerid",tempid);
            return new CmdResVo(0);
        }

        MPJLambdaWrapper<FiCreditcases> quyWrapper=getQueryWrapper(triggerid);
        if(quyWrapper==null){
            log.warn("caseDistribute({}).nofind trigger={}",tempid,triggerid);
            return new CmdResVo(0);
        }
        List<Integer> dataCaseList=caseService.selectJoinList(Integer.class,
                quyWrapper.select(FiCreditcases::getCreditcaseid)
                        .eq(FiCreditcases::getCcc, EnumFiCaseQueue.O.name)
        );
        if(JPubUtils.IsEmpty(dataCaseList)){
            log.info("caseDistribute({}).nofind ficasedata",tempid);
            return new CmdResVo(0);
        }
        List<CfgActivityOthergrplink> othergrplinks=othergrplinkMapper.selectJoinList(CfgActivityOthergrplink.class,
                new MPJLambdaWrapper<CfgActivityOthergrplink>()
                        .eq(CfgActivityOthergrplink::getActivityid,tempid)
        );
        if(JPubUtils.IsEmpty(othergrplinks)){
            log.info("caseDistribute({}).nofind distgrpinfo",tempid);
            return new CmdResVo(0);
        }
        List<ValRadioVo> grplist=new ArrayList<>();
        for(CfgActivityOthergrplink link : othergrplinks){
            ValRadioVo radioVo=new ValRadioVo();
            radioVo.setKey(link.getGrpid());
            if(link.getRadio()!=null) {
                radioVo.setRadio(link.getRadio() * 1.0);
            }
            grplist.add(radioVo);
        }
        String $usrid=user.getUsrid();
        DistReqVo paras=new DistReqVo();
        SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
        if(JPubUtils.IsEqual(domode,"1")) {
            paras.setBatchid("A5" + sdf.format(new Date()));
            paras.setBatchname("自动执行批次分案");
        }
        else{
            paras.setBatchid("M5"+sdf.format(new Date()));
            paras.setBatchname("手动执行批次分案");
        }
        paras.setActiontype(Integer.parseInt(domode));
        paras.setDismode(activity.getDistype2());
        paras.setDistype(activity.getDistype());
        paras.setBinddays(activity.getBindday());
        paras.setPridelay(1);
        paras.setFicaseList(dataCaseList);
        paras.setGrpList(grplist);

        List<DistResVo> distResVoList=caseService.preDistribute(paras,dataCaseList);

        log.info("caseDistribute({}).preDistribute.Ok..",tempid);

        caseService.doDistCaseTo(distResVoList,paras.getBatchid(),
                $usrid, paras.getBinddays(), paras.getActiontype(),
                paras.getDismode(),paras.getBatchname(),amirate
        );

        log.info("caseDistribute({}).doDistCaseTo.Ok..",tempid);
        int cnt=dataCaseList.size();
        distResVoList.clear();
        dataCaseList.clear();

        return new CmdResVo(cnt);
    }

    @Override
    public CmdResVo caseAssign(JSysUser user,String grpid,String domode,Integer assmode)
    { //domode=1手动，=2自动
        List<CfgAssignratio> assignratioList = assignratioMapper.selectList(
                new MPJLambdaWrapper<CfgAssignratio>().eq(CfgAssignratio::getGrpid,grpid)
        );
        if (JPubUtils.IsEmpty(assignratioList)){
            log.warn("caseAssign({}).nofind assignratio",grpid);
            return new CmdResVo(0);
        }

        List<Integer> dataCaseList=caseService.selectJoinList(Integer.class,
                new MPJLambdaWrapper<FiCreditcases>()
                        .select(FiCreditcases::getCreditcaseid)
                        .eq(FiCreditcases::getStatus, EnumFiCaseStatus.Distribute.value)
                        .eq(FiCreditcases::getSendtodept,grpid)
        );
        if(JPubUtils.IsEmpty(dataCaseList)){
            log.info("caseAssign({}).nofind ficasedata",grpid);
            return new CmdResVo(0);
        }

        List<ValRadioVo> userlist=new ArrayList<>();
        for(CfgAssignratio p : assignratioList){
            ValRadioVo radioVo=new ValRadioVo();
            radioVo.setKey(p.getUsrid());
            if(p.getRatio()!=null) {
                radioVo.setRadio(p.getRatio() * 1.0);
            }
            userlist.add(radioVo);
        }
        String $usrid=user.getUsrid();
        AssReqVo paras=new AssReqVo();
        SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
        if(JPubUtils.IsEqual(domode,"1")) {
            paras.setBatchid("A6" + sdf.format(new Date()));
        }
        else{
            paras.setBatchid("M6"+sdf.format(new Date()));
        }
        paras.setActiontype(Integer.parseInt(domode));
        //分配模式，1：平均分配，2:按金额比例分配，3：按数量比例分配
        paras.setAssmode(assmode);
        paras.setActiontype(Integer.parseInt(domode));
        paras.setFicaseList(dataCaseList);
        paras.setUsrList(userlist);

        List<DistResVo> distResVoList=caseService.preAssign(paras,dataCaseList);
        log.info("caseAssign({}).preAssign.Ok..",grpid);
        caseService.doAssignCaseTo(distResVoList,paras.getBatchid(),
                $usrid, paras.getActiontype(),
                assmode,null,null
        );
        log.info("caseAssign({}).doAssignCaseTo.Ok..",grpid);
        int cnt=dataCaseList.size();
        distResVoList.clear();
        dataCaseList.clear();

        return new CmdResVo(cnt);
    }
}
